#include "src/gui/SettingsDialog.h"

#include <qlayout.h>
//Added by qt3to4:
#include <QLabel>
#include <QHBoxLayout>
#include <QVBoxLayout>

SettingsDialog::SettingsDialog( string *account, 
                                string *password, 
                                string *server,
                                string *homeChannel,
                                string *cdkey,
                                string *starcraftVersion,
                                string *hashfileLocation1,
                                string *hashfileLocation2,
                                string *hashfileLocation3 )
    : saveDataFilename( "gitmchatSettings.dat" ),
      fileVersion( 5 )
{

    this->setCaption("Settings");

  // Make sure there are no null pointers.
  if(account == 0 || password == 0 || server == 0 || 
     homeChannel == 0 || cdkey == 0 || 
     starcraftVersion == 0 ||
     hashfileLocation1 == 0 || 
     hashfileLocation2 == 0 || 
     hashfileLocation3 == 0 )
  {
    done(QDialog::Rejected);
  }

  // Copy string pointers.
  username_ = account;
  password_ = password;
  server_   = server;
  homeChannel_ = homeChannel;
  cdkey_ = cdkey;
  starcraftVersion_  = starcraftVersion;
  hashfileLocation1_ = hashfileLocation1;
  hashfileLocation2_ = hashfileLocation2;
  hashfileLocation3_ = hashfileLocation3;

  
  usernameLabel_ = new QLabel(tr("Username:  "), this);
  passwordLabel_ = new QLabel(tr("Password:  "), this);
  serverLabel_   = new QLabel(tr("Gateway/Server:"), this);
  homeChannelLabel_ = new QLabel(tr("Home Channel:"), this);
  cdkeyLabel_    = new QLabel(tr("CD Key(no spaces):"), this);
  starcraftVersionLabel_  = new QLabel(tr("Starcraft version:"), this);
  hashfileLocation1Label_ = new QLabel(tr("Location of starcraft.exe:"), this);
  hashfileLocation2Label_ = new QLabel(tr("Location of storm.dll:"), this);
  hashfileLocation3Label_ = new QLabel(tr("Location of battle.snp:"), this);

  usernameLineEdit_ = new QLineEdit(this);
  passwordLineEdit_ = new QLineEdit(this);
  passwordLineEdit_->setEchoMode(QLineEdit::Password);

  serverSelect_ = new QComboBox(this);
  serverSelect_->insertItem("useast.battle.net");
  serverSelect_->insertItem("uswest.battle.net");
  serverSelect_->insertItem("europe.battle.net");
  serverSelect_->insertItem("asia.battle.net");

  homeChannelLineEdit_ = new QLineEdit(this);
  cdkeyLineEdit_       = new QLineEdit(this);
  starcraftVersionLineEdit_  = new QLineEdit(this);
  hashfileLocation1LineEdit_ = new QLineEdit(this);
  hashfileLocation2LineEdit_ = new QLineEdit(this);
  hashfileLocation3LineEdit_ = new QLineEdit(this);

  loginButton_ = new QPushButton(tr("&Log in"), this);
  exitButton_  = new QPushButton(tr("E&xit"), this);

  browseHashfileLocation1Button_ = new QPushButton(tr("Browse"), this);
  browseHashfileLocation2Button_ = new QPushButton(tr("Browse"), this);
  browseHashfileLocation3Button_ = new QPushButton(tr("Browse"), this);

  usernameSaveCheckBox_ = new QCheckBox( tr("Save"), this );
  passwordSaveCheckBox_ = new QCheckBox( tr("Save"), this );
  serverSaveCheckBox_ = new QCheckBox( tr("Save"), this );
  homeChannelSaveCheckBox_ = new QCheckBox( tr("Save"), this );
  cdkeySaveCheckBox_ = new QCheckBox( tr("Save"), this );
  starcraftVersionSaveCheckBox_  = new QCheckBox( tr("Save"), this );
  hashfileLocation1SaveCheckBox_ = new QCheckBox( tr("Save"), this );
  hashfileLocation2SaveCheckBox_ = new QCheckBox( tr("Save"), this );
  hashfileLocation3SaveCheckBox_ = new QCheckBox( tr("Save"), this );

  QHBoxLayout *usernameLayout = new QHBoxLayout;
  usernameLayout->addWidget( usernameLabel_ );
  usernameLayout->addWidget( usernameLineEdit_ );
  usernameLayout->addWidget( usernameSaveCheckBox_ );

  QHBoxLayout *passwordLayout = new QHBoxLayout;
  passwordLayout->addWidget( passwordLabel_ );
  passwordLayout->addWidget( passwordLineEdit_ );
  passwordLayout->addWidget( passwordSaveCheckBox_ );

  QHBoxLayout *serverLayout = new QHBoxLayout;
  serverLayout->addWidget( serverLabel_ );
  serverLayout->addWidget( serverSelect_ );
  serverLayout->addWidget( serverSaveCheckBox_ );

  QHBoxLayout *homeChannelLayout = new QHBoxLayout;
  homeChannelLayout->addWidget( homeChannelLabel_ );
  homeChannelLayout->addWidget( homeChannelLineEdit_ );
  homeChannelLayout->addWidget( homeChannelSaveCheckBox_ );

  QHBoxLayout *cdkeyLayout = new QHBoxLayout;
  cdkeyLayout->addWidget( cdkeyLabel_ );
  cdkeyLayout->addWidget( cdkeyLineEdit_ );
  cdkeyLayout->addWidget( cdkeySaveCheckBox_ );

  QHBoxLayout *starcraftVersionLayout = new QHBoxLayout;
  starcraftVersionLayout->addWidget( starcraftVersionLabel_ );
  starcraftVersionLayout->addWidget( starcraftVersionLineEdit_ );
  starcraftVersionLayout->addWidget( starcraftVersionSaveCheckBox_ );

  QHBoxLayout *hashfileLocation1Layout = new QHBoxLayout;
  hashfileLocation1Layout->addWidget( hashfileLocation1Label_ );
  hashfileLocation1Layout->addWidget( hashfileLocation1LineEdit_ );
  hashfileLocation1Layout->addWidget( browseHashfileLocation1Button_ );
  hashfileLocation1Layout->addWidget( hashfileLocation1SaveCheckBox_ );

  QHBoxLayout *hashfileLocation2Layout = new QHBoxLayout;
  hashfileLocation2Layout->addWidget( hashfileLocation2Label_ );
  hashfileLocation2Layout->addWidget( hashfileLocation2LineEdit_ );
  hashfileLocation2Layout->addWidget( browseHashfileLocation2Button_ );
  hashfileLocation2Layout->addWidget( hashfileLocation2SaveCheckBox_ );

  QHBoxLayout *hashfileLocation3Layout = new QHBoxLayout;
  hashfileLocation3Layout->addWidget( hashfileLocation3Label_ );
  hashfileLocation3Layout->addWidget( hashfileLocation3LineEdit_ );
  hashfileLocation3Layout->addWidget( browseHashfileLocation3Button_ );
  hashfileLocation3Layout->addWidget( hashfileLocation3SaveCheckBox_ );

  QVBoxLayout *top = new QVBoxLayout;
  top->addLayout( usernameLayout );
  top->addLayout( passwordLayout );
  top->addLayout( serverLayout );
  top->addLayout( homeChannelLayout );
  top->addLayout( cdkeyLayout );
  top->addLayout( starcraftVersionLayout );
  top->addLayout( hashfileLocation1Layout );
  top->addLayout( hashfileLocation2Layout );
  top->addLayout( hashfileLocation3Layout );
  
  QHBoxLayout *bottom = new QHBoxLayout;
  bottom->addWidget( loginButton_ );
  bottom->addWidget( exitButton_ );
  
  QVBoxLayout *mainLayout = new QVBoxLayout(this);
  mainLayout->addLayout( top );
  mainLayout->addSpacing( 20 );  
  mainLayout->addLayout( bottom );
  
  if( !loadSettings() )
  {
      loadDefaultSettings();
  }

  connect( browseHashfileLocation1Button_, SIGNAL(clicked()),
           this, SLOT(browseForHashfileLocation1ButtonClicked()) );
  connect( browseHashfileLocation2Button_, SIGNAL(clicked()),
           this, SLOT(browseForHashfileLocation2ButtonClicked()) );
  connect( browseHashfileLocation3Button_, SIGNAL(clicked()),
           this, SLOT(browseForHashfileLocation3ButtonClicked()) );
  connect( loginButton_, SIGNAL(clicked()),
           this, SLOT(loginButtonClicked()) );
  connect( exitButton_, SIGNAL(clicked()),
           this, SLOT(exitButtonClicked()) );

}



string SettingsDialog::getUsername() 
{
    qtusername_ = usernameLineEdit_->text();
    return string(qtusername_.ascii());
}


string SettingsDialog::getPassword() 
{
    qtpassword_ = passwordLineEdit_->text();
    return string(qtpassword_.ascii());
}


string SettingsDialog::getServer() 
{
    qtserver_ = serverSelect_->currentText();
    return string(qtserver_.ascii());
}


string SettingsDialog::getHomeChannel()
{  
    qthomeChannel_ = homeChannelLineEdit_->text();
    return string(qthomeChannel_.ascii());
}


string SettingsDialog::getCdkey()
{
    qtcdkey_ = cdkeyLineEdit_->text();
    return string(qtcdkey_.ascii());
}

string SettingsDialog::getStarcraftVersion()
{
    qtstarcraftVersion_ = starcraftVersionLineEdit_->text();
    return string(qtstarcraftVersion_.ascii());
}

string SettingsDialog::getHashfileLocation1()
{
    qthashfileLocation1_ = hashfileLocation1LineEdit_->text();
    return string(qthashfileLocation1_.ascii());
}


string SettingsDialog::getHashfileLocation2()
{
    qthashfileLocation2_ = hashfileLocation2LineEdit_->text();
    return string(qthashfileLocation2_.ascii());
}


string SettingsDialog::getHashfileLocation3()
{
    qthashfileLocation3_ = hashfileLocation3LineEdit_->text();
    return string(qthashfileLocation3_.ascii());
}


void SettingsDialog::browseForHashfileLocation1ButtonClicked()
{
    QFileDialog fd(this);
    
    fd.setWindowTitle( "Hashfile 'starcraft.exe' File Dialog" );
    fd.setFileMode(QFileDialog::ExistingFile);
    fd.setFilter( "Hashfile1 (starcraft.exe)" );

    // Get the file name:
    QStringList filenames;
    if( fd.exec() )
    {
        // They selected a new file, so set the text with the new file name.
        filenames = fd.selectedFiles();
        hashfileLocation1LineEdit_->setText( filenames.first() );
    }
}


void SettingsDialog::browseForHashfileLocation2ButtonClicked()
{
    QFileDialog fd(this);

    fd.setWindowTitle( "Hashfile 'storm.dll' File Dialog" );
    fd.setFileMode(QFileDialog::ExistingFile);
    fd.setFilter( "Hashfile2 (storm.dll)" );

    // Get the file name:
    QStringList filenames;
    if( fd.exec() )
    {
        // They selected a new file, so set the text with the new file name.
        filenames = fd.selectedFiles();
        hashfileLocation2LineEdit_->setText( filenames.first() );
    }
}


void SettingsDialog::browseForHashfileLocation3ButtonClicked()
{
    QFileDialog fd(this);
    
    fd.setWindowTitle( "Hashfile 'battle.snp' File Dialog" );
    fd.setFileMode(QFileDialog::ExistingFile);
    fd.setFilter( "Hashfile3 (battle.snp)" );

    // Get the file name:
    QStringList filenames;
    if( fd.exec() )
    {
        // They selected a new file, so set the text with the new file name.
        filenames = fd.selectedFiles();
        hashfileLocation3LineEdit_->setText( filenames.first() );
    }
}

void SettingsDialog::loginButtonClicked() 
{
    // Calling saveSettings() will refresh and update the class's
    // member variables.
    saveSettings();

    // Copy over the values to the parent class's targets.
    (*username_) = getUsername();
    (*password_) = getPassword();
    (*server_)   = getServer();
    (*homeChannel_) = getHomeChannel();
    (*cdkey_)    = getCdkey();
    (*starcraftVersion_)  = getStarcraftVersion();
    (*hashfileLocation1_) = getHashfileLocation1();
    (*hashfileLocation2_) = getHashfileLocation2();
    (*hashfileLocation3_) = getHashfileLocation3();
  
    hide();
    accept();
}

void SettingsDialog::exitButtonClicked() 
{
  hide();
  reject();
}


// Load a C++ boolean value (stored as a Q_UINT8) from the
// QDataStream.  Make sure that there is enough in the stream to read
// this value in!
bool SettingsDialog::loadBool( QDataStream& in )
{
    // Temp variable.
    Q_UINT8 someBoolean;

    in >> someBoolean;

    if( someBoolean == 0 )
    {
	return false;
    }
    else
    {
	return true;
    }
}


// Loads the settings.
bool SettingsDialog::loadSettings()
{
    // If there are no saved settings, then load the defaults.
    if( !QFile::exists( saveDataFilename ) )
    {
        return false;
    }

    // Try to open the file.
    QFile file( saveDataFilename );
    if( !file.open( QIODevice::ReadOnly ) )
    {
	// Problems opening the file.
	QMessageBox::warning( this, tr("Load Failed!"),
			      tr("Could not open ") + saveDataFilename +
			      tr(" for loading saved settings." ) );
	return false;
    }
    
    // Create a QDataStream for reading in from.
    QDataStream in( &file );
    
    // Read the magic number to make sure it's a good file.
    Q_UINT32 fileMagicNumber;
    Q_UINT32 fileVersionNumber;

    in >> fileMagicNumber;
    
    if( fileMagicNumber != MagicNumber )
    {
	QMessageBox::warning( this, tr("Load Failed!"),
			      tr("The saved settings file ") + 
                              saveDataFilename +
			      tr(" is corrupt.  You may want to delete " ) +
                              tr("the file to avoid this message in the " ) +
                              tr("future.") );
	return false;
    }
    
    in >> fileVersionNumber;
    
    if( fileVersionNumber != fileVersion )
    {
	QMessageBox::warning( this, tr("Load Failed!"),
			      tr("The version number of the saved datafile ")
			      + saveDataFilename + tr(" is wrong.  ") +
                              tr("You may want to delete " ) +
                              tr("the file to avoid this message in the " ) +
                              tr("future.") );
	return false;
    }
    

    // Load the saved data.
    saveUsernameEnabled_ = this->loadBool( in );
    savePasswordEnabled_ = this->loadBool( in );
    saveServerEnabled_   = this->loadBool( in );
    saveHomeChannelEnabled_ = this->loadBool( in );
    saveCdkeyEnabled_    = this->loadBool( in );
    saveStarcraftVersionEnabled_  = this->loadBool( in );
    saveHashfileLocation1Enabled_ = this->loadBool( in );
    saveHashfileLocation2Enabled_ = this->loadBool( in );
    saveHashfileLocation3Enabled_ = this->loadBool( in );


    in >> qtusername_;
    in >> qtpassword_;
    in >> qtserver_;
    in >> serverComboBoxIndex_;
    in >> qthomeChannel_;
    in >> qtcdkey_;
    in >> qtstarcraftVersion_;
    in >> qthashfileLocation1_;
    in >> qthashfileLocation2_;
    in >> qthashfileLocation3_;


    // Set the widgets.
    usernameSaveCheckBox_->setChecked( saveUsernameEnabled_ );
    passwordSaveCheckBox_->setChecked( savePasswordEnabled_ );
    serverSaveCheckBox_->setChecked( saveServerEnabled_ );
    homeChannelSaveCheckBox_->setChecked( saveHomeChannelEnabled_ );
    cdkeySaveCheckBox_->setChecked( saveCdkeyEnabled_ );
    starcraftVersionSaveCheckBox_->setChecked( saveStarcraftVersionEnabled_ );
    hashfileLocation1SaveCheckBox_->setChecked( saveHashfileLocation1Enabled_);
    hashfileLocation2SaveCheckBox_->setChecked( saveHashfileLocation2Enabled_);
    hashfileLocation3SaveCheckBox_->setChecked( saveHashfileLocation3Enabled_);

    if( saveUsernameEnabled_ == true )
    {
        usernameLineEdit_->setText( qtusername_ );
    }

    if( savePasswordEnabled_ == true )
    {
        passwordLineEdit_->setText( qtpassword_ );
    }

    if( saveServerEnabled_ == true )
    {
        serverSelect_->setCurrentItem( serverComboBoxIndex_ );
    }
    
    if( saveHomeChannelEnabled_ == true )
    {
        homeChannelLineEdit_->setText( qthomeChannel_ );
    }

    if( saveCdkeyEnabled_ == true )
    {
        cdkeyLineEdit_->setText( qtcdkey_ );
    }

    if( saveStarcraftVersionEnabled_ == true )
    {
        starcraftVersionLineEdit_->setText( qtstarcraftVersion_ );
    }

    if( saveHashfileLocation1Enabled_ == true )
    {
        hashfileLocation1LineEdit_->setText( qthashfileLocation1_ );
    }

    if( saveHashfileLocation2Enabled_ == true )
    {
        hashfileLocation2LineEdit_->setText( qthashfileLocation2_ );
    }

    if( saveHashfileLocation3Enabled_ == true )
    {
        hashfileLocation3LineEdit_->setText( qthashfileLocation3_ );
    }

    return true;
}

// Loads the default settings.
void SettingsDialog::loadDefaultSettings()
{
    // Unless the setting is specifically specified here, every other
    // setting should be blank or unchecked. (aside from the combo box).

    homeChannelLineEdit_->setText( "Op Git'em" );
    starcraftVersionLineEdit_->setText( "1.13f" );

    cdkeySaveCheckBox_->setChecked( true );
    usernameSaveCheckBox_->setChecked( true );
    passwordSaveCheckBox_->setChecked( false );
    serverSaveCheckBox_->setChecked( true );
    homeChannelSaveCheckBox_->setChecked( true );
    cdkeySaveCheckBox_->setChecked( true );
    starcraftVersionSaveCheckBox_->setChecked( true );
    hashfileLocation1SaveCheckBox_->setChecked( true );
    hashfileLocation2SaveCheckBox_->setChecked( true );
    hashfileLocation3SaveCheckBox_->setChecked( true );
    starcraftVersionSaveCheckBox_->setChecked( true );
}

// Loads the default settings.
bool SettingsDialog::saveSettings()
{
    // Save the states of the combo boxes that indicate to save the
    // value or not.
    saveUsernameEnabled_ = usernameSaveCheckBox_->isEnabled();
    savePasswordEnabled_ = passwordSaveCheckBox_->isEnabled();
    saveServerEnabled_ = serverSaveCheckBox_->isEnabled();
    saveHomeChannelEnabled_ = homeChannelSaveCheckBox_->isEnabled();
    saveCdkeyEnabled_ = cdkeySaveCheckBox_->isEnabled();
    saveStarcraftVersionEnabled_ = starcraftVersionSaveCheckBox_->isEnabled();
    saveHashfileLocation1Enabled_ = 
        hashfileLocation1SaveCheckBox_->isEnabled();
    saveHashfileLocation2Enabled_ = 
        hashfileLocation2SaveCheckBox_->isEnabled();
    saveHashfileLocation3Enabled_ = 
        hashfileLocation3SaveCheckBox_->isEnabled();

    qtusername_ = usernameLineEdit_->text();
    qtpassword_ = passwordLineEdit_->text();
    qtserver_   = serverSelect_->currentText();
    serverComboBoxIndex_ = serverSelect_->currentItem();
    qthomeChannel_       = homeChannelLineEdit_->text();
    qtcdkey_             = cdkeyLineEdit_->text();
    qtstarcraftVersion_  = starcraftVersionLineEdit_->text();
    qthashfileLocation1_ = hashfileLocation1LineEdit_->text();
    qthashfileLocation2_ = hashfileLocation2LineEdit_->text();
    qthashfileLocation3_ = hashfileLocation3LineEdit_->text();

    // Open the file as write.
    QFile file( saveDataFilename );
    if( !file.open( QIODevice::WriteOnly ) )
    {
	QMessageBox::warning( this, tr("Save Failed!"),
			      tr("Could not open file ") + saveDataFilename +
			      tr(" for saving settings.") );
	return false;
    }
    
    QDataStream out( &file );
    out.setVersion( 5 );
    out << (Q_UINT32)MagicNumber;
    out << (Q_UINT32)fileVersion;
    out << (Q_UINT8)saveUsernameEnabled_;
    out << (Q_UINT8)savePasswordEnabled_;
    out << (Q_UINT8)saveServerEnabled_;
    out << (Q_UINT8)saveHomeChannelEnabled_;
    out << (Q_UINT8)saveCdkeyEnabled_;
    out << (Q_UINT8)saveStarcraftVersionEnabled_;
    out << (Q_UINT8)saveHashfileLocation1Enabled_;
    out << (Q_UINT8)saveHashfileLocation2Enabled_;
    out << (Q_UINT8)saveHashfileLocation3Enabled_;
    out << qtusername_;
    out << qtpassword_;
    out << qtserver_;
    out << (Q_UINT32)serverComboBoxIndex_;
    out << qthomeChannel_;
    out << qtcdkey_;
    out << qtstarcraftVersion_;
    out << qthashfileLocation1_;
    out << qthashfileLocation2_;
    out << qthashfileLocation3_;

    // From qt3.
    //     if( file.status() != IO_Ok )
    //     {
    // 	QMessageBox::warning( this, tr("Save Failed!"),
    // 			      tr("Error writing settings to file ") +
    // 			      saveDataFilename );
    // 	return false;
    //     }

    return true;
    
}
